/*
 * TEST003.pde
 * read pressure sensor data from Arduino and draw chart.
 *
 * written by elekid.
 * 
 * Processing site :  http://processing.org
 */
import processing.serial.*;

Serial port;
PFont bigFont;
PFont myFont;
PFont labelFont;

String inString="";
int cnt=0;

static int DATASIZE = 200;
float[] data = new float[DATASIZE];
String[] tag = new String[DATASIZE];

static int chartX = 50;
static int chartY = 10;
static int chartWidth = 420;
static int chartHeight = 320;

color dataColor = color(24, 24,128 );
color msgColor = color(255,0,0);
color lineColor = color(128);

float maxdata;
float mindata;
int intMaxdata;
int intMindata;


// for future use
static int midBaro=1000;
static int defaultMaxBaro=1020;
static int defaultMinBaro=1000;

/**
 *   setup()
 */
void setup(){
  myFont = createFont("SansSerif", 18); 
  labelFont= createFont("SansSerif", 10); 
  bigFont = createFont("SansSerif", 24); 

  println(Serial.list());
  size (480,360);

  // Assuming that 3rd serial port is connected to Arduino
  port = new Serial(this, Serial.list()[2], 9600); 
  port.bufferUntil(10);
  frameRate(1);

  for ( int i =0 ; i < DATASIZE ; i++){
    data[i]=0;
  }

  // outfile = createWriter("data.txt");

  // DEBUG
  cnt=102;
  addData(1010.55, "23:26");
  addData(1010.54, "23:41");
  addData(1010.38, "23:56");
  addData(1010.47, "00:11");
  addData(1010.45, "00:26");
  addData(1010.46, "00:40");
  addData(1010.61, "00:55");
  addData(1010.64, "01:10");
  addData(1010.66, "01:25");
  addData(1010.64, "01:40");
  addData(1010.52, "01:55");
  addData(1010.45, "02:10");
  addData(1010.49, "02:25");
  addData(1010.30, "02:40");
  addData(1009.95, "02:55");
  addData(1010.14, "03:10");
  addData(1010.11, "03:25");
  addData(1010.00, "03:40");
  addData(1010.03, "03:55");
  addData(1010.10, "04:10");
  addData(1010.19, "04:25");
  addData(1010.23, "04:40");
  addData(1010.29, "04:55");
  addData(1010.41, "05:09");
  addData(1010.53, "05:24");
  addData(1010.67, "05:39");
  addData(1010.65, "05:54");
  addData(1010.73, "06:09");
  addData(1010.94, "06:24");
  addData(1010.26, "06:39");
  addData(1010.29, "06:54");
  addData(1010.68, "07:09");
  addData(1010.70, "07:24");
  addData(1010.65, "07:39");
  addData(1010.62, "07:54");
  addData(1010.57, "08:09");
  addData(1010.28, "08:24");
  addData(1010.28, "08:39");
  addData(1010.23, "08:54");
  addData(1010.02, "09:09");
  addData(1009.86, "09:24");
  addData(1009.98, "09:38");
  addData(1009.72, "09:53");
  addData(1009.94, "10:08");
  addData(1010.13, "10:23");
  addData(1009.74, "10:38");
  addData(1009.62, "10:53");
  addData(1009.42, "11:08");
  addData(1009.01, "11:23");
  addData(1008.87, "11:38");
  addData(1008.53, "11:53");
  addData(1008.29, "12:08");
  addData(1008.17, "12:23");
  addData(1008.20, "12:38");
  addData(1008.01, "12:53");
  addData(1007.90, "13:08");
  addData(1007.45, "13:23");
  addData(1007.03, "13:38");
  addData(1006.74, "13:53");
  addData(1006.82, "14:08");
  addData(1006.46, "14:22");
  addData(1006.28, "14:37");
  addData(1006.23, "14:52");
  addData(1006.34, "15:07");
  addData(1005.91, "15:22");
  addData(1005.91, "15:37");
  addData(1005.41, "15:52");
  addData(1005.54, "16:07");
  addData(1005.52, "16:22");
  addData(1005.51, "16:37");
  addData(1005.44, "16:52");
  addData(1005.00, "17:07");
  addData(1005.25, "17:22");
  addData(1005.29, "17:37");
  addData(1004.78, "17:52");
  addData(1004.73, "18:07");
  addData(1004.77, "18:22");
  addData(1004.70, "18:37");
  addData(1005.47, "18:51");
  addData(1005.51, "19:06");
  addData(1005.51, "19:21");
  addData(1005.01, "19:36");
  addData(1005.85, "19:51");
  addData(1005.98, "20:06");
  addData(1006.27, "20:21");
  addData(1006.33, "20:36");
  addData(1006.39, "20:51");
  addData(1006.54, "21:06");
  addData(1006.51, "21:31");
addData(1006.55, "21:33");
addData(1006.52, "21:35");
addData(1005.91, "21:36");
addData(1005.92, "21:39");
addData(1005.93, "21:39");
addData(1006.57, "21:54");
addData(1006.47, "22:09");
addData(1006.46, "22:24");
addData(1006.57, "22:39");
addData(1006.43, "22:53");
addData(1006.54, "23:08");
addData(1006.38, "23:23");
addData(1006.29, "23:38");



  // DEBUG END
}

/**
 *   draw()
 */
void draw(){
  int pos_y;
  background(210);
  smooth();

  // draw graph area
  noStroke();
  fill(240);
  rect( chartX, chartY, chartWidth, chartHeight);

  // draw graph
  plotDataLabel();
  drawChart();

  // display current value  
  textFont(myFont, 18);
  fill(msgColor);
  text ("now : ",  170 , chartY + 20 );
  textFont(bigFont, 24);
  text(int(data[0]), 215, chartY + 20);
  textFont(myFont, 18);
  text ("hPa",  275 , chartY + 20 );

  /*
  fill(0);
   textFont(myFont, 18); 
   text(buffer, 30, pos_y);
   */
}


/**
 *   serialEvent()
 *
 *   automatically called when Serial data is available.
 */
void serialEvent(Serial p) { 

  inString = (port.readString()); 
  saveLogFile(inString);
  cnt++;

  String msg=String.format("%02d", hour())  + ":" +String.format("%02d", minute());

  String[] s=split(inString, " ");
  println(s[0] + " / " + msg);

  addData(float(s[0]), msg);

}

/**
 *   addData()
 *
 *   store sensor data into array
 */
void addData(float hpa, String msg) {
  for ( int i=DATASIZE-1 ; i > 0 ; i--){
    data[i]=data[i-1];
    tag[i] = tag[i-1];
  }
  data[0] =hpa;
  tag[0] = msg;

  maxdata = data[0] ; 
  mindata = data[0] ;

  for ( int i = 1 ; i < DATASIZE ; i++) {
    if ( data[i] > maxdata ){
      maxdata = data[i];
    }
    if (data[i] < mindata && data[i] > 0 ){
      mindata = data[i];
    }
  }

  if ( ( maxdata - mindata ) < 4 ) {
    maxdata = maxdata + 2 ;
    mindata = mindata -2 ;
  }

  println("max : " + maxdata );
  println("min : " + mindata );

  // outfile.println(hpa);
  // outfile.flush();

}


/**
 *   drawChart()
 *
 *   draw line chart
 */
void drawChart(){
  stroke(dataColor);
  noFill();
  strokeWeight(2);
  beginShape();
  for (int i = 0 ; i <cnt ; i++){
    if (i >= DATASIZE ) break;

    float x = getX(i);
    float y = getY(data[i]);
    /*
    print(data[i] + " ");
     print(x);
     print(" ");
     println(y);
     */

    curveVertex( x ,y );
    if ( i-1 == cnt || i == 0) {
      curveVertex( x ,y );
    }
  }

  endShape();
}

/**
 *   plotDataLabel()
 *
 *   plot x/y axis labels
 */
void plotDataLabel(){
  intMindata  = int(mindata);
  intMaxdata = int(maxdata)+1;
  textFont(labelFont,10);
  for ( int v = intMindata ; v <= intMaxdata ; v++) {
    noFill();
    strokeWeight(1);
    stroke(lineColor);
    line ( chartX , getY(v), chartX+chartWidth, getY(v));
    fill(dataColor);
    text(v,chartX-30,getY(v)+5);

  }

  for ( int v = 0 ; v < DATASIZE ; v += 4) {
    noFill();
    strokeWeight(1);
    stroke(lineColor);
    line ( getX(v) , getY(intMaxdata), getX(v), getY(intMindata));
  }

  for ( int v = 0 ; v < DATASIZE ; v+=8) {
    if ( v >= cnt ) break;
    pushMatrix();
    translate(getX(v),getY(intMindata)+30);
    rotate(PI*3/2);
    fill(dataColor);
    text(tag[v],0,0);
    popMatrix();

  }
}

/*
 * getX()
 *
 *   calc x value
 */
float getX (int cnt){
  float x = chartX + chartWidth - (cnt * chartWidth / DATASIZE);
  return x;
}

/*
 * getY()
 *
 *   calc y value
 */
float getY(float val){
  float y = chartY + (1 + intMaxdata - val) * chartHeight / (intMaxdata - intMindata+2);
  return y;
}

/*
 *  saveLogFile()
 *
 *  save sensor data into log file
 */
void saveLogFile(String outString) {
  String buffer = "[";
  buffer += String.valueOf(year());
  buffer += "/";
  buffer += String.valueOf(month());
  buffer += "/";
  buffer += String.valueOf(day());
  buffer += " ";
  buffer += String.format("%02d", hour());
  buffer += ":";
  buffer += String.format("%02d", minute());
  buffer += ":";
  buffer += String.format("%02d", second());
  buffer += "]  ";
  buffer += outString;

  String[] lines = loadStrings("sensor_data.log");
  String[] newlines= append( lines, buffer);
  saveStrings("sensor_data.log", newlines);
  print(buffer);

}



